/**
 * Markdown 渲染组件
 * Phase 1: 前端 MVP 使用
 * 
 * 功能：
 * - GitHub 风格 Markdown 渲染
 * - 代码语法高亮
 * - 表格支持
 * - 自动生成标题锚点 ID（用于目录跳转）
 * - 代码块复制按钮
 * - 数学公式支持（KaTeX）
 * - 标签页支持
 */

import React, { useState } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import remarkAlert from 'remark-github-blockquote-alert';
import remarkEmoji from 'remark-emoji';
import remarkCodeTitle from 'remark-code-title';
import remarkFootnotes from 'remark-footnotes';
// import remarkIns from 'remark-ins'; // 暂时不用，GFM 不支持 ==text== 语法
import rehypeRaw from 'rehype-raw';
import rehypeHighlight from 'rehype-highlight';
import rehypeSlug from 'rehype-slug';
import rehypeKatex from 'rehype-katex';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Check, Copy, AlertTriangle, Info, AlertCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { MarkdownTabs } from './markdown-tabs';
import { MarkdownMindmap } from './markdown-mindmap';
import { MarkdownPdfViewer } from './markdown-pdf-viewer';
import { MarkdownMermaid } from './markdown-mermaid';
import { extractTextFromChildren, copyToClipboard } from './markdown-config';

// 导入 KaTeX 样式
import 'katex/dist/katex.min.css';

/**f
 * 纯 Markdown 渲染器（不处理标签页，用于标签页内部内容）
 * @param {Object} props
 * @param {string} props.content - Markdown 内容
 * @param {string} props.className - 自定义样式类
 * @param {boolean} props.enableCopyButton - 是否启用代码块复制按钮（默认 true）
 */
export const PureMarkdownRenderer = ({ content, className = '', enableCopyButton = true }) => {
  const [copiedCode, setCopiedCode] = useState(null);

  // 复制代码块（使用共享函数）
  const handleCopyCode = async (code, index) => {
    const success = await copyToClipboard(code);
    if (success) {
      setCopiedCode(index);
      setTimeout(() => setCopiedCode(null), 2000);
    }
  };

  // 自定义组件
  const components = {
    // div 组件 - 拦截 remark-github-blockquote-alert 生成的提示框 和 remark-code-title 生成的文件名
    div({ children, className, ...props }) {
      // 检查是否是代码文件名标签
      if (className?.includes('remark-code-title')) {
        return (
          <div className="bg-gray-700 dark:bg-gray-800 text-gray-200 dark:text-gray-300 px-4 py-2 text-sm rounded-t-lg border border-gray-600 dark:border-gray-700 flex items-center gap-2 not-prose">
            <svg className="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
            </svg>
            <span className="font-mono">{children}</span>
          </div>
        );
      }

      // 检查是否是 GitHub Alert
      if (className?.includes('markdown-alert')) {
        // 提取 alert 类型
        const alertType = className
          .split(' ')
          .find(cls => cls.startsWith('markdown-alert-'))
          ?.replace('markdown-alert-', '');

        // 移除子元素中的 <p> 标签包裹（防止 <div> 嵌套 <p> 错误）
        const cleanChildren = React.Children.map(children, child => {
          // 如果是 <p> 标签，只保留其子内容
          if (child?.props?.node?.tagName === 'p') {
            return child.props.children;
          }
          return child;
        });

        // 根据类型渲染不同的提示框
        switch (alertType) {
          case 'note':
          case 'tip':
            return (
              <div className="my-4 p-4 bg-blue-50 dark:bg-blue-950 border-l-4 border-blue-500 rounded-r-lg not-prose">
                <div className="flex items-start gap-3">
                  <Info className="size-5 text-blue-500 flex-shrink-0 mt-0.5" />
                  <div className="flex-1 text-sm text-blue-900 dark:text-blue-100">
                    {cleanChildren}
                  </div>
                </div>
              </div>
            );

          case 'warning':
          case 'caution':
            return (
              <div className="my-4 p-4 bg-yellow-50 dark:bg-yellow-950 border-l-4 border-yellow-500 rounded-r-lg not-prose">
                <div className="flex items-start gap-3">
                  <AlertTriangle className="size-5 text-yellow-500 flex-shrink-0 mt-0.5" />
                  <div className="flex-1 text-sm text-yellow-900 dark:text-yellow-100">
                    {cleanChildren}
                  </div>
                </div>
              </div>
            );

          case 'important':
          case 'danger':
            return (
              <div className="my-4 p-4 bg-red-50 dark:bg-red-950 border-l-4 border-red-500 rounded-r-lg not-prose">
                <div className="flex items-start gap-3">
                  <AlertCircle className="size-5 text-red-500 flex-shrink-0 mt-0.5" />
                  <div className="flex-1 text-sm text-red-900 dark:text-red-100">
                    {cleanChildren}
                  </div>
                </div>
              </div>
            );
        }
      }

      // 普通 div
      return <div className={className} {...props}>{children}</div>;
    },

    // 代码块组件
    code({ inline, className, children, ...props }) {
      // 内联代码
      if (inline) {
        return (
          <code
            className="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 text-sm rounded border border-gray-200 dark:border-gray-700 font-mono text-pink-600 dark:text-pink-400"
            {...props}
          >
            {children}
          </code>
        );
      }

      // 代码块 - 直接返回 code 元素
      return (
        <code className={className} {...props}>
          {children}
        </code>
      );
    },

    // 代码块的 pre 标签（处理复制按钮和特殊语法）
    pre({ children, ...props }) {
      // 提取代码内容和语言
      const codeElement = children?.props;
      const className = codeElement?.className || '';
      const match = /language-(\w+)/.exec(className);
      const language = match ? match[1] : '';

      // 从 codeElement.children 中提取文本
      const code = extractTextFromChildren(codeElement?.children || '').replace(/\n$/, '');
      const codeIndex = `${language}-${code.substring(0, 20)}`;

      // 检测特殊代码块类型
      if (language === 'mindmap') {
        return <MarkdownMindmap content={code} />;
      }

      if (language === 'pdf') {
        return <MarkdownPdfViewer url={code.trim()} />;
      }

      if (language === 'mermaid') {
        return <MarkdownMermaid content={code} type="mermaid" />;
      }

      return (
        <div className="relative group my-4 not-prose">
          {/* 语言标签 */}
          {language && (
            <div className="absolute left-4 top-3 z-10">
              <Badge variant="secondary" className="text-xs">
                {language}
              </Badge>
            </div>
          )}

          {/* 复制按钮 - 可选 */}
          {enableCopyButton && (
            <Button
              type="button"
              variant="ghost"
              size="sm"
              className="absolute right-2 top-2 opacity-0 group-hover:opacity-100 transition-opacity z-10"
              onClick={() => handleCopyCode(code, codeIndex)}
            >
              {copiedCode === codeIndex ? (
                <>
                  <Check className="size-4 mr-1 text-green-500" />
                  已复制
                </>
              ) : (
                <>
                  <Copy className="size-4 mr-1" />
                  复制
                </>
              )}
            </Button>
          )}

          {/* 代码内容 */}
          <pre
            className="overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 p-4 pt-12"
            {...props}
          >
            {children}
          </pre>
        </div>
      );
    },

    // 引用块（普通引用，GitHub Alert 已被插件转换为 div）
    blockquote({ children, ...props }) {
      // 移除子元素中多余的 <p> 包裹（防止 <blockquote><p><p> 嵌套错误）
      const cleanChildren = React.Children.map(children, child => {
        // 如果是 <p> 标签，只保留其子内容
        if (child?.props?.node?.tagName === 'p') {
          return child.props.children;
        }
        return child;
      });

      return (
        <blockquote
          className="my-4 pl-4 border-l-4 border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 italic not-prose"
          {...props}
        >
          {cleanChildren}
        </blockquote>
      );
    },

    // 表格
    table({ children, ...props }) {
      return (
        <div className="my-6 overflow-x-auto">
          <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded-lg" {...props}>
            {children}
          </table>
        </div>
      );
    },

    thead({ children, ...props }) {
      return (
        <thead className="bg-gray-50 dark:bg-gray-800" {...props}>
          {children}
        </thead>
      );
    },

    th({ children, ...props }) {
      return (
        <th
          className="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider"
          {...props}
        >
          {children}
        </th>
      );
    },

    td({ children, ...props }) {
      return (
        <td
          className="px-4 py-3 text-sm text-gray-900 dark:text-gray-100 border-t border-gray-200 dark:border-gray-700"
          {...props}
        >
          {children}
        </td>
      );
    },

    // 标题
    h1({ children, ...props }) {
      return (
        <h1
          className="text-4xl font-bold mt-8 mb-4 pb-2 border-b-2 border-gray-200 dark:border-gray-700"
          {...props}
        >
          {children}
        </h1>
      );
    },

    h2({ children, ...props }) {
      return (
        <h2
          className="text-3xl font-bold mt-8 mb-4 pb-2 border-b border-gray-200 dark:border-gray-700"
          {...props}
        >
          {children}
        </h2>
      );
    },

    h3({ children, ...props }) {
      return (
        <h3
          className="text-2xl font-bold mt-6 mb-3"
          {...props}
        >
          {children}
        </h3>
      );
    },

    h4({ children, ...props }) {
      return (
        <h4
          className="text-xl font-bold mt-4 mb-2"
          {...props}
        >
          {children}
        </h4>
      );
    },

    // 链接
    a({ children, href, ...props }) {
      const isExternal = href?.startsWith('http');

      return (
        <a
          href={href}
          className="text-blue-600 dark:text-blue-400 hover:underline"
          target={isExternal ? '_blank' : undefined}
          rel={isExternal ? 'noopener noreferrer' : undefined}
          {...props}
        >
          {children}
          {isExternal && (
            <span className="inline-block ml-1 text-xs">↗</span>
          )}
        </a>
      );
    },

    // 列表
    ul({ children, ...props }) {
      return (
        <ul
          className="my-4 ml-6 list-disc space-y-2 text-gray-700 dark:text-gray-300"
          {...props}
        >
          {children}
        </ul>
      );
    },

    ol({ children, ...props }) {
      return (
        <ol
          className="my-4 ml-6 list-decimal space-y-2 text-gray-700 dark:text-gray-300"
          {...props}
        >
          {children}
        </ol>
      );
    },

    // 段落
    p({ children, className, node, ...props }) {
      // 隐藏 GitHub Alert 自动生成的标题（我们已经有图标了）
      if (className?.includes('markdown-alert-title')) {
        return null;
      }

      // 检查节点的原始信息，看是否包含需要提升的元素
      // 1. 检查是否只包含单个 img 元素且是 PDF
      if (node?.children?.length === 1 && node?.children[0]?.tagName === 'img') {
        const imgNode = node.children[0];
        const src = imgNode?.properties?.src || '';
        if (src.toLowerCase().endsWith('.pdf')) {
          // 这是 PDF，直接返回 children（已经被 img 组件转换为 MarkdownPdfViewer）
          return <>{children}</>;
        }
      }

      // 递归检查 children 中是否包含 block 级元素
      const hasBlockElement = (element) => {
        if (!element) return false;
        
        // 检查组件类型
        const type = element?.type;
        const typeName = type?.name || type?.displayName || type;
        
        if (typeName === 'MarkdownPdfViewer' || 
            typeName === 'MarkdownMindmap' ||
            typeName === 'MarkdownMermaid' ||
            typeName === 'MarkdownTabs') {
          return true;
        }
        
        // 检查 className
        const elClassName = element?.props?.className || '';
        if (elClassName.includes('not-prose') ||
            elClassName.includes('my-6 border') ||
            elClassName.includes('markdown-alert')) {
          return true;
        }
        
        // 检查是否是 block 级 DOM 元素
        if (type === 'div' || type === 'pre' || type === 'table') {
          return true;
        }
        
        // 检查节点标签名
        const tagName = element?.props?.node?.tagName;
        if (tagName === 'div' || tagName === 'pre' || tagName === 'table') {
          return true;
        }
        
        // 递归检查子元素
        if (element?.props?.children) {
          const childrenArray = React.Children.toArray(element.props.children);
          if (childrenArray.some(hasBlockElement)) {
            return true;
          }
        }
        
        return false;
      };

      // 检查当前 children
      const childrenArray = React.Children.toArray(children);
      const shouldUnwrap = childrenArray.some(hasBlockElement);

      if (shouldUnwrap) {
        return <>{children}</>;
      }

      return (
        <p
          className="my-4 text-base leading-7 text-gray-700 dark:text-gray-300"
          {...props}
        >
          {children}
        </p>
      );
    },

    // 分隔线
    hr({ ...props }) {
      return (
        <hr
          className="my-8 border-t border-gray-200 dark:border-gray-700"
          {...props}
        />
      );
    },

    // 图片（支持 PDF 文件）
    img({ src, alt, ...props }) {
      // 检测是否是 PDF 文件
      if (src?.toLowerCase().endsWith('.pdf')) {
        return <MarkdownPdfViewer url={src} />;
      }

      // 普通图片
      return (
        <img
          src={src}
          alt={alt}
          className="max-w-full h-auto rounded-lg shadow-md my-4"
          loading="lazy"
          {...props}
        />
      );
    },

    // SVG - 隐藏插件自动生成的图标（我们使用 lucide-react 图标）
    svg({ className, ...props }) {
      // 隐藏 octicon 图标
      if (className?.includes('octicon')) {
        return null;
      }
      // 普通 SVG
      return <svg className={className} {...props} />;
    },

    // 高亮文本（==text==）- remark-ins 会生成 <ins> 标签
    ins({ children, ...props }) {
      return (
        <mark 
          className="bg-yellow-200 dark:bg-yellow-900 text-gray-900 dark:text-gray-100 px-1 rounded" 
          {...props}
        >
          {children}
        </mark>
      );
    },

    // mark 标签（备用）
    mark({ children, ...props }) {
      return (
        <mark 
          className="bg-yellow-200 dark:bg-yellow-900 text-gray-900 dark:text-gray-100 px-1 rounded" 
          {...props}
        >
          {children}
        </mark>
      );
    },

    // 键盘按键 (<kbd>Ctrl</kbd>)
    kbd({ children, ...props }) {
      return (
        <kbd 
          className="px-2 py-1 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md text-xs font-mono shadow-sm inline-block"
          {...props}
        >
          {children}
        </kbd>
      );
    },

    // 脚注引用（上标链接）
    sup({ children, ...props }) {
      return (
        <sup 
          className="text-primary hover:underline cursor-pointer"
          {...props}
        >
          {children}
        </sup>
      );
    },

    // 脚注列表部分
    section({ className, children, ...props }) {
      // 检查是否是脚注部分
      if (className?.includes('footnotes')) {
        return (
          <section 
            className="mt-12 pt-6 border-t-2 border-gray-200 dark:border-gray-700 not-prose"
            {...props}
          >
            <h2 className="text-lg font-semibold text-foreground mb-4">📝 脚注</h2>
            <div className="space-y-2 text-sm text-gray-700 dark:text-gray-300">
              {children}
            </div>
          </section>
        );
      }
      return <section className={className} {...props}>{children}</section>;
    }
  };

  // 渲染纯 Markdown 内容（不处理标签页）
  // 注意：不在这里添加 prose 类，由外层容器控制
  return (
    <div className={cn("markdown-body", className)}>
      <ReactMarkdown
        remarkPlugins={[
          remarkGfm,        // GitHub 风格 Markdown（表格、删除线等）
          remarkMath,       // 数学公式解析
          remarkAlert,      // GitHub 风格提示框（[!NOTE] 等）
          remarkEmoji,      // Emoji 表情支持 (:emoji:)
          remarkCodeTitle,  // 代码块文件名支持
          [remarkFootnotes, { inlineNotes: true }]  // 脚注支持
        ]}
        rehypePlugins={[
          rehypeRaw,       // 允许渲染 HTML 标签（<mark>, <kbd> 等）
          rehypeHighlight, // 代码高亮
          rehypeSlug,      // 为标题添加 id（用于目录跳转）
          rehypeKatex      // 数学公式渲染（KaTeX）
        ]}
        components={components}
      >
        {content || '*暂无内容*'}
      </ReactMarkdown>
    </div>
  );
};

/**
 * 主 Markdown 渲染器（支持标签页预处理）
 * @param {Object} props
 * @param {string} props.content - Markdown 内容
 * @param {string} props.className - 自定义样式类
 */
const MarkdownRenderer = ({ content, className = '' }) => {
  // 预处理标签页内容（HTML 注释语法）
  const processTabsContent = (text) => {
    if (!text) return [];

    const parts = [];
    const tabsRegex = /<!--\s*tabs:start\s*-->([\s\S]*?)<!--\s*tabs:end\s*-->/g;
    let lastIndex = 0;
    let match;
    let tabsIndex = 0;

    while ((match = tabsRegex.exec(text)) !== null) {
      // 添加标签页之前的普通内容
      if (match.index > lastIndex) {
        parts.push({
          type: 'markdown',
          content: text.substring(lastIndex, match.index)
        });
      }

      // 添加标签页内容
      parts.push({
        type: 'tabs',
        content: match[1].trim(),
        key: `tabs-${tabsIndex++}`
      });

      lastIndex = match.index + match[0].length;
    }

    // 添加最后剩余的普通内容
    if (lastIndex < text.length) {
      parts.push({
        type: 'markdown',
        content: text.substring(lastIndex)
      });
    }

    return parts.length > 0 ? parts : [{ type: 'markdown', content: text }];
  };

  const contentParts = processTabsContent(content);

  return (
    <>
      {contentParts.map((part, index) => {
        if (part.type === 'tabs') {
          return <MarkdownTabs key={part.key || index} content={part.content} />;
        }
        // 使用 PureMarkdownRenderer 渲染普通 Markdown
        return (
          <PureMarkdownRenderer
            key={index}
            content={part.content || ''}
            enableCopyButton={true}
            className={className}
          />
        );
      })}
    </>
  );
};

export default MarkdownRenderer;

